home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
satellit
/
pbq
/
pbq.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-21
|
11KB
|
409 lines
/*******************************************************************\
* *
* PBQ - Pacsat Broadcast Queue/Query Purge *
* *
* This program helps you purge the directory of partially-received *
* files generated by PB. For each partial file in the directory, *
* PBQ tells you everything it can figure out about the file. It *
* then asks what you want to do with the file. If you wish to *
* continue receiving the file, PBQ does nothing. If you wish to *
* delete the partial files for now, PBQ deletes the files for you. *
* If you wish to ignore that file number forever, PBQ deletes the *
* partial files and creates a dummy .DL file (0 bytes long) so *
* that PB won't ever try to receive that file again. *
* *
* Compiled with Microsoft C 6.00AX: *
* cl -W3 pbq.c *
* *
\*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <dos.h>
#include <errno.h>
#include <graph.h>
#include <conio.h>
#include "dirlist.h"
int main(void);
void init_directory(void);
void process_partial_file(char *holname);
unsigned long summarize_dir_info(unsigned long file_number);
void print_entry(dir_entry entry);
void summarize_hole_file(char *holname, unsigned long file_length);
void end_pbq(void);
void hitanykey(void);
int get_option(char *opts);
int delete_files(char *holname, char *actname);
/* The PG.DIR directory file. Opened and initially scanned by
* one routine, then indexed-read by another. */
FILE *dirfile = NULL;
#define DIRMAX 1000
struct findex_entry /* Index to the directory file */
{
unsigned long fileno;
unsigned long offset;
} findex[DIRMAX];
int number_of_entries;
/* Show a length as BAD_LENGTH if we don't really know it */
#define BAD_LENGTH (0xFFFFFFFF)
/* Keep a few statistics */
int files_kept = 0;
int files_deleted = 0;
int files_faked = 0;
int main(void)
{
struct find_t fileinfo;
_clearscreen(_GCLEARSCREEN); /* clear the entire screen */
printf("PBQ - Pacsat Broadcast Queue/Query Purge 1.0\n");
printf("Copyright 1991 Paul Williamson, KB5MU\n\n");
_settextwindow(4, 1, 25, 80); /* All per-file output fits in here */
/* Get rid of the old hole files */
if (_dos_findfirst("*.OLH", _A_NORMAL, &fileinfo) == 0)
do {
remove(fileinfo.name);
}
while (_dos_findnext(&fileinfo) == 0);
/* Now ask about each partially received file */
if (_dos_findfirst("*.HOL", _A_NORMAL, &fileinfo) != 0)
{
printf("No partially downloaded files exist.\n");
exit(1);
}
init_directory(); /* Go get the directory info so we can look up fast */
/* Now scan thru all the partial files and do our thing */
do {
process_partial_file(fileinfo.name);
}
while (_dos_findnext(&fileinfo) == 0);
end_pbq(); /* Report a few statistics and exit */
return 0;
}
void end_pbq(void)
{
_clearscreen(_GWINDOW);
_settextposition(14, 10);
printf("<C>ontinued: %d", files_kept);
_settextposition(15, 10);
printf("<D>eleted: %d", files_deleted);
_settextposition(16, 10);
printf("<F>aked out: %d", files_faked);
_settextposition(20, 10);
exit(0);
}
/*******************************************************\
* *
* init_directory *
* Open PG.DIR, and scan through it once and record the *
* fseek cookie for each file number. *
* *
\*******************************************************/
void init_directory(void)
{
int i;
dir_entry entry;
if ((dirfile = fopen("PG.DIR", "rb")) == NULL)
{
printf("Can't open PG.DIR.\n");
return;
}
i = 0;
findex[i].offset = ftell(dirfile);
while (!feof(dirfile) && !ferror(dirfile))
{
if (!fread((void *) &entry, sizeof entry, (size_t) 1, dirfile))
{
if (ferror(dirfile))
{
printf("Error reading PG.DIR.\n");
exit(1);
}
}
else
{
findex[i].fileno = entry.fileno;
//printf("Dir entry %lx at %lx\n", findex[i].fileno, findex[i].offset); //debug
if (++i >= DIRMAX) /* don't overrun the array */
break;
findex[i].offset = ftell(dirfile); /* cookie points to next entry */
}
}
number_of_entries = i-1;
}
/**********************************************************\
* *
* process_partial_file *
* *
* This routine is called for each partially received file *
* in the directory. It displays whatever information it *
* can find, and then asks the user what to do. *
* *
\**********************************************************/
void process_partial_file(char *holname)
{
char rootname[13];
char actname[13];
unsigned long fileno;
unsigned long filelen;
FILE *fakefile;
_clearscreen(_GWINDOW); /* Clear away old per-file info */
_settextposition(4, 1);
/* Play with the filenames a bit */
strcpy(rootname, holname);
*strchr(rootname, '.') = '\0'; /* trim off the extension */
strcpy(actname, rootname);
strcat(actname, ".ACT");
if (sscanf(holname, "%lx.HOL", &fileno) != 1)
{
printf("What's this? A non-numeric filename (%s)? Ignored.\n",
rootname);
return;
}
printf("File Number: %s\n", rootname);
filelen = summarize_dir_info(fileno);
summarize_hole_file(holname, filelen);
_settextposition(14, 10);
printf("<C>ontinue to receive this file (PBQ does nothing)");
_settextposition(15, 10);
printf("<D>elete this partially received file");
_settextposition(16, 10);
printf("<F>ake out PB with a dummy .DL file");
_settextposition(17, 10);
printf("<Q>uit PBQ");
_settextposition(19, 10);
printf("C D F Q : ");
switch(get_option("CDFQ"))
{
case 'C':
files_kept++;
break;
case 'F':
strcat(rootname, ".DL");
if ((fakefile = fopen(rootname, "w")) == NULL)
{
printf("\nCouldn't create fake .DL file!\n");
hitanykey();
}
else
{
files_faked++;
delete_files(holname, actname);
fclose(fakefile);
}
break;
case 'D':
if (delete_files(holname, actname))
files_deleted++;
break;
case 'Q':
end_pbq();
}
}
/**************************************************************\
* *
* summarize_dir_info *
* *
* This routine finds the directory entry for a given file, *
* if any. It then summarizes the info to stdout. It returns *
* the length of the file according to the directory. *
* *
\**************************************************************/
unsigned long summarize_dir_info(unsigned long file_number)
{
int i;
char tstr[12]; // put the time string here
struct tm *tm_p;
dir_entry entry;
for (i=0; i<number_of_entries; i++)
if (findex[i].fileno == file_number)
break;
if (i >= number_of_entries)
return BAD_LENGTH; /* No directory entry found; return bad length */
if (fseek(dirfile, findex[i].offset, SEEK_SET) != 0)
return BAD_LENGTH; /* Can't seek. Return bad length */
if (!fread((void *) &entry, sizeof entry, (size_t) 1, dirfile))
return BAD_LENGTH; /* Can't read. Return bad length */
tm_p = gmtime(&(entry.time));
sprintf(tstr, "%02d/%02d %02d:%02d",
tm_p->tm_mon+1, tm_p->tm_mday, tm_p->tm_hour, tm_p->tm_min);
printf(" To: %8.8s\n"
" From: %8.8s\n"
" Time: %11s\n"
" Title: %-39.39s\n",
entry.to, entry.from, tstr, entry.title);
if (entry.keywords[0] != '\0') /* Don't display empty keywords field */
printf(" Keywords: %-19.19s\n", entry.keywords);
return entry.filesize;
}
/*********************************************************\
* *
* summarize_hole_file *
* *
* This routine reads the hole file for a given file, and *
* summarizes the statistics to stdout. *
* *
\*********************************************************/
void summarize_hole_file(char *holname, unsigned long file_length)
{
FILE *holfile;
int header_received;
unsigned long hlength;
unsigned long nholes, h;
unsigned long bytes_received = 0;
unsigned long bytes_missing = 0;
unsigned long last_address = 0;
unsigned long hfrom, hto;
if (((holfile = fopen(holname, "r")) == NULL)
||
(fscanf(holfile,
"%d pfh header received\n"
"%ld pfh file length\n"
"%ld holes",
&header_received, &hlength, &nholes) != 3))
{
printf("Can't scan .HOL file!\n");
if (file_length != BAD_LENGTH)
printf(" Length: %ld\n", file_length);
if (holfile != NULL)
fclose(holfile);
return;
}
for (h=0; h<nholes; h++)
{
if (fscanf(holfile, " %ld, %ld", &hfrom, &hto) != 2)
{
printf("Can't scan .HOL file!\n");
if (file_length != BAD_LENGTH)
printf(" Length: %ld\n", file_length);
fclose(holfile);
return;
}
bytes_received += (hfrom - last_address);
if (hto != 0xFFFFFFFF)
bytes_missing += (hto + 1 - hfrom);
last_address = hto + 1;
}
if (header_received)
{
printf(" Length: %ld", hlength);
if (hlength != file_length)
printf(" (PG.DIR said %ld)", file_length);
printf("\n Status: %d%% complete, %ld holes\n",
(int)(((hlength-bytes_missing)*100)/hlength), nholes);
}
else if (file_length != BAD_LENGTH)
{
bytes_missing += (file_length - hfrom);
printf(" Length: %ld\n", file_length);
printf(" Status: %d%% complete, %ld holes\n",
(int)(((file_length-bytes_missing)*100)/file_length), nholes);
}
else
{
printf(" Status: %ld bytes received, %ld+ bytes in %ld holes.\n",
bytes_received, bytes_missing, nholes);
}
}
void hitanykey(void)
{
int key;
printf("Hit any key to continue ...");
key = getch();
if (key == '\0' || key == 0xE0)
getch(); /* do the right thing with function keys */
}
int get_option(char *opts)
{
int key;
do {
key = getch();
if (key == 0 || key == 0xE0)
{
getch();
key = -1;
continue;
}
}
while (strchr(opts, toupper(key)) == NULL);
return toupper(key);
}
int delete_files(char *holname, char *actname)
{
if (remove(holname))
{
printf("\nCouldn't delete hole file!\n");
hitanykey();
return 0;
}
if (remove(actname) && errno != ENOENT)
{
printf("\nCouldn't delete .ACT file!\n");
hitanykey();
return 0;
}
return 1;
}